package com.zghhost.codedemo.concurrent.queue;

import com.google.common.util.concurrent.ThreadFactoryBuilder;

import java.util.AbstractQueue;
import java.util.concurrent.*;

/**
 * @author guohua.zhang@zhaopin.com.cn
 * @Date 2019/4/12 15:32
 */
public class QueueTest {
    private static AbstractQueue<Integer> nbqueue;
    private static BlockingQueue<Integer> bqueue;

    private static ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat("test-poor-%d").build();
    private static ExecutorService pool = new ThreadPoolExecutor(10, 10,
            0L, TimeUnit.MILLISECONDS,
            new LinkedBlockingQueue<Runnable>(1024),
            threadFactory);
    private static ExecutorService npool = new ThreadPoolExecutor(10, 10,
            0L, TimeUnit.MILLISECONDS,
            new LinkedBlockingQueue<Runnable>(1024),
            threadFactory);


    public static void main(String[] args){
        case1();
        case2();
    }

    public static void workBQueue(BlockingQueue<Integer> queue){
        QueueTest.bqueue = queue;

        //创建一个线程向队列中方数据
        pool.execute(()->{
            try{
                for(int i=0,ic=10000 * 10000;i<ic;i++){
                    queue.put(i);
//                    System.out.println("我是生产者我向队列中放入了一个 "+i);
                }
            }catch (Exception e){}
        });
        //创建一个线程从队列中消费数据
        pool.execute(()->{
            try{
                for(int i=0,ic=10000 * 10000;i<ic;i++){
                    int val = queue.take();
//                    System.out.println("我是消费者我从队列中取出了一个 "+val);
                }
            }catch (Exception e){}
        });
        pool.shutdown();
        //监听两个任务执行完花费时间
        new Thread(()->{
            Long sts = System.currentTimeMillis();
            while(true){
                if(pool.isTerminated()){
                    System.out.println("队列执行完毕");
                    break;
                }
            }
            Long ets = System.currentTimeMillis();
            Long cts = ets - sts;
            System.out.println("workBQueue花费"+(cts/1000/60)+"分钟"+(cts/1000%60)+"秒");
        }).start();
    }

    public static void workQueue(AbstractQueue queue){
        QueueTest.nbqueue = queue;

        //创建一个线程向队列中方数据
        npool.execute(()->{
            try{
                for(int i=0,ic=10000 * 10000;i<ic;i++){
                    queue.offer(i);
//                    System.out.println("我是生产者我向队列中放入了一个 "+i);
                }
            }catch (Exception e){}
        });
        //创建一个线程从队列中消费数据
        npool.execute(()->{
            try{
                for(int i=0,ic=10000 * 10000;i<ic;i++){
                    Integer val = (Integer) queue.poll();
//                    System.out.println("我是消费者我从队列中取出了一个 "+val);
                }
            }catch (Exception e){}
        });
        npool.shutdown();
        //监听两个任务执行完花费时间
        new Thread(()->{
            Long sts = System.currentTimeMillis();
            while(true){
                if(npool.isTerminated()){
                    System.out.println("队列执行完毕");
                    break;
                }
            }
            Long ets = System.currentTimeMillis();
            Long cts = ets - sts;
            System.out.println("workQueue花费"+(cts/1000/60)+"分钟"+(cts/1000%60)+"秒");
        }).start();
    }

    public static void case1(){
        //阻塞队列
        BlockingQueue<Integer> queue = new LinkedBlockingQueue<Integer>(100);
        workBQueue(queue);
    }

    public static void case2(){
        AbstractQueue queue = new ConcurrentLinkedQueue();
        workQueue(queue);
    }
}
